package com.libinshen.wxpay.videoAliBaBa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.libinshen.wxpay.OSSAliYun.service.OssService;
import com.libinshen.wxpay.common.enums.CourseStatusEnums;
import com.libinshen.wxpay.videoAliBaBa.entity.Chapter;
import com.libinshen.wxpay.videoAliBaBa.entity.Comment;
import com.libinshen.wxpay.videoAliBaBa.entity.Course;
import com.libinshen.wxpay.videoAliBaBa.entity.CourseDescription;
import com.libinshen.wxpay.videoAliBaBa.entity.Video;
import com.libinshen.wxpay.videoAliBaBa.entity.form.CourseInfoForm;
import com.libinshen.wxpay.videoAliBaBa.entity.vo.CoursePublishVo;
import com.libinshen.wxpay.videoAliBaBa.entity.vo.CourseQueryVo;
import com.libinshen.wxpay.videoAliBaBa.entity.vo.CourseVo;
import com.libinshen.wxpay.videoAliBaBa.mapper.ChapterMapper;
import com.libinshen.wxpay.videoAliBaBa.mapper.CommentMapper;
import com.libinshen.wxpay.videoAliBaBa.mapper.CourseCollectMapper;
import com.libinshen.wxpay.videoAliBaBa.mapper.CourseMapper;
import com.libinshen.wxpay.videoAliBaBa.mapper.VideoMapper;
import com.libinshen.wxpay.videoAliBaBa.service.CourseDescriptionService;
import com.libinshen.wxpay.videoAliBaBa.service.CourseService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author lbs
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    @Resource
    private CourseDescriptionService courseDescriptionService;

    @Resource
    private VideoMapper videoMapper;

    @Resource
    private ChapterMapper chapterMapper;

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private CourseCollectMapper courseCollectMapper;

    @Resource
    private OssService ossService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveCourseInfo(CourseInfoForm courseInfoForm) {
        //1:保存课程基本信息
        Course course = new Course();
        course.setStatus(CourseStatusEnums.DRAFT.getCode());
        BeanUtils.copyProperties(courseInfoForm, Course.class);
        boolean resultCourseInfo = this.save(course);
        if (!resultCourseInfo) {
            return null;
        }

        //保存课程简介信息
        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setDescription(courseInfoForm.getDescription());
        courseDescription.setId(course.getId());
        courseDescriptionService.save(courseDescription);
        return course.getId();
    }

    @Override
    public CourseInfoForm getCourseInfoById(String id) {
        CourseInfoForm courseInfoForm = null;

        Course course = baseMapper.selectById(id);
        if (course == null) {
            return courseInfoForm;
        }

        BeanUtils.copyProperties(course, courseInfoForm);
        CourseDescription courseDescription = courseDescriptionService.getById(id);
        courseInfoForm.setDescription(courseDescription.getDescription());
        return courseInfoForm;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void updateCourseInfoById(CourseInfoForm courseInfoForm) {
        //更新course
        Course course = new Course();
        BeanUtils.copyProperties(courseInfoForm, course);
        baseMapper.updateById(course);

        //更新CourseDescription
        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setDescription(courseInfoForm.getDescription());
        courseDescription.setId(courseInfoForm.getId());
        courseDescriptionService.updateById(courseDescription);
    }

    @Override
    public IPage<CourseVo> selectPage(Long page, Long limit, CourseQueryVo courseQueryVo) {
        //组装查询条件
        QueryWrapper<CourseVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("c.create_time");

        String title = courseQueryVo.getTitle();
        Integer teacherId = courseQueryVo.getTeacherId();
        String subjectParentId = courseQueryVo.getSubjectParentId();
        String subjectId = courseQueryVo.getSubjectId();

        if (StringUtils.isEmpty(title)) {
            queryWrapper.like("c.title", title);
        }

        if (!StringUtils.isEmpty(teacherId.toString())) {
            queryWrapper.like("c.teacher_id", teacherId);
        }

        if (!StringUtils.isEmpty(subjectParentId)) {
            queryWrapper.like("c.subject_parent_id", subjectParentId);
        }

        if (!StringUtils.isEmpty(subjectId)) {
            queryWrapper.like("c.subject_id", subjectId);
        }

        /****
         *该方法涉及到多表联查以及查询之后对数据进行分页操作。
         * 重要的是如何对查询出来的数据进行分页
         */
        Page<CourseVo> pageParam = new Page<>(page, limit);
        //放入分页参数和查询条件参数，mp会自动组装。这句话很重要
        List<CourseVo> records = baseMapper.selectPageByCourseQueryVo(pageParam, queryWrapper);
        pageParam.setRecords(records);
        return pageParam;
    }


    /***
     * 互联网分布式项目中
     * 不得使用外键和级联，一切外键概念必须在应用层解决。
     * 一切涉及级联的操作不要依赖数据层。要在业务层解决。
     *
     * 先删叶子节点表【原因是避免有外键】，再删父表。
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCourseInfoById(String id) {
        //1：删除课程封面图片
        removeCoverById(id);

        //2：删除课程视频。视频点播 TODO


        //3:根据courseId删除Video
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("course_id", id);
        videoMapper.delete(videoQueryWrapper);

        //4：根据课程Id删除章节信息
        QueryWrapper<Chapter> chapterQueryWrapper = new QueryWrapper<>();
        chapterQueryWrapper.eq("course_id", id);
        chapterMapper.delete(chapterQueryWrapper);

        //删除课程评论
        QueryWrapper<Comment> commentQueryWrapper = new QueryWrapper<>();
        commentQueryWrapper.eq("course_id", id);
        commentMapper.delete(commentQueryWrapper);

        //5：删除课程简介
        courseDescriptionService.removeById(id);

        //5：删除课程基本信息数据
        return this.removeById(id);
    }

    @Override
    public boolean removeCoverById(String id) {
        if (StringUtils.isEmpty(id)) {
            return false;
        }

        Course course = baseMapper.selectById(id);
        if (course != null) {
            String cover = course.getCover();
            if (!StringUtils.isEmpty(cover)) {
                //调用oss服务删除文件 TODO
                return true;
            }
        }

        return false;
    }

    @Override
    public CoursePublishVo getCoursePublishVoById(String id) {
        return baseMapper.getCoursePublishVoById(id);
    }

    @Override
    public boolean publishCourseById(String id) {
        Course course = new Course();
        course.setId(id);
        course.setStatus(CourseStatusEnums.NORMAL.getCode());
        Integer count = baseMapper.updateById(course);
        return null != count && count > 0;
    }
}
